package ui {
	import flash.events.FocusEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.ui.Mouse;
	import flash.ui.MouseCursor;
	public class Spinner extends TextBox {
		public var min:Number = NaN;
		public var max:Number = NaN;
		public var step:Number = 0.25;
		public var restrictStep:Boolean = false;
		private var v:Number = 0;
		
		private static var dragging:Boolean = false;
		
		private var over:Boolean = false;
		private var originalValue:Number;
		private var offset:Point = new Point();
		
		public function Spinner(label:String, options:Object = null) {
			super(label, "", options);
			
			//marginTop += 3;
			
			labelTxt.mouseEnabled = true;
			labelTxt.addEventListener(MouseEvent.ROLL_OVER, rollOver);
			labelTxt.addEventListener(MouseEvent.ROLL_OUT, rollOut);
			labelTxt.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
			addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheel);
			text = ""+v;
			
			content.y = height/2-content.height/2-3;
		}
		
		public function get value():Number { return v; }
		public function set value(val:Number):void {
			v = val;
			updateValue(false);
		}
		
		private function mouseWheel(e:MouseEvent):void {
			v += e.delta > 0 ? step : -step;
			//v += e.delta*step;
			updateValue();
			e.updateAfterEvent();
		}
		
		private function rollOver(e:MouseEvent):void {
			over = true;
			updateCursor();
		}
		
		private function updateCursor():void{
			Mouse.cursor = over || dragging ? MouseCursor.HAND : MouseCursor.AUTO;
		}
		
		private function rollOut(e:MouseEvent = null):void {
			over = false;
			updateCursor();
		}
		
		private function mouseDown(e:MouseEvent):void {
			offset.x = mouseX;
			originalValue = v;
			stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
			dragging = true;
		}
		
		private function mouseMove(e:MouseEvent):void {
			v = originalValue+(mouseX-offset.x)*step;
			updateValue();
			e.updateAfterEvent();
		}
		
		private function updateValue(dispatch:Boolean = true):void {
			if (restrictStep) v = Math.round(v/step)*step;
			v = Math.round(v*1e13)/1e13;
			if (!isNaN(min) && v < min) v = min;
			else if (!isNaN(max) && v > max) v = max;
			text = ""+v;
			if (dispatch) dispatchEvent(new ValueEvent(ValueEvent.VALUE_CHANGED, v));
		}
		
		override protected function updateChange():void {
			v = Number(text);
			updateValue();
		}
		
		private function mouseUp(e:MouseEvent):void {
			dragging = false;
			updateCursor();
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
			stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
		}
		
	}
}